package com.torry.workflow.service.user.facade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.torry.workflow.api.user.api.RoleApi;
import com.torry.workflow.api.user.entity.*;
import com.torry.workflow.common.exception.BizException;
import com.torry.workflow.service.user.service.*;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@DubboService
@Component
public class RoleFacade implements RoleApi {

    @Resource
    private IRoleService iRoleService;

    @Resource
    private IUserRoleService iUserRoleService;

    @Resource
    private IRoleMenuService iRoleMenuService;
    @Resource
    private IRolePermService iRolePermService;
    @Resource
    private IRoleOrgService iRoleOrgService;
    @Resource
    private IMenuService iMenuService;
    @Resource
    private IOrgService iOrgService;
    @Resource
    private IPermService iPermService;

    @Override
    public List<Role> getAllRoles() {
        List<Role> list = iRoleService.list(new QueryWrapper<Role>().eq("deleted", 0));

        return list;
    }


    @Override
    public Role getRoleInfoById(Integer id) {
        Role role = iRoleService.getOne(new QueryWrapper<Role>().eq("deleted", 0).eq("id", id));


        // 获取角色配置的菜单
        List<Integer> menuIds = iRoleMenuService.listObjs(new QueryWrapper<RoleMenu>().select("menu_id").eq("deleted", 0).eq("role_id", id),
                (menuId) -> Integer.parseInt(menuId.toString()));
        if (CollectionUtils.isNotEmpty(menuIds)) {
            role.setMenuIds(menuIds);
        }

        // 获取角色配置的权限
        List<Integer> permIds = iRolePermService.listObjs(new QueryWrapper<RolePerm>().select("perm_id").eq("deleted", 0).eq("role_id", id),
                (permId) -> Integer.parseInt(permId.toString()));
        if (CollectionUtils.isNotEmpty(permIds)) {
            role.setPermIds(permIds);
        }

        // 获取角色配置的部门
        List<Integer> orgIds = iRoleOrgService.listObjs(new QueryWrapper<RoleOrg>().select("org_id").eq("deleted", 0).eq("role_id", id),
                (orgId) -> Integer.parseInt(orgId.toString()));
        if (CollectionUtils.isNotEmpty(orgIds)) {
            role.setOrgIds(orgIds);
        }

        return role;
    }

    @Override
    @Transactional
    public void saveRoleBaseInfo(Role role) {
        if (roleNameIsExist(role)) {
            throw new BizException(400, "角色名已存在");
        }
        iRoleService.saveOrUpdate(role);
    }

    private boolean roleNameIsExist(Role role) {
        Role roleInfo = iRoleService.getOne(new QueryWrapper<Role>().eq("deleted", 0).eq("name", role.getName()));
        if (role.getId() == null) {
            return roleInfo != null;
        }
        return roleInfo != null && !roleInfo.getId().equals(role.getId());
    }

    @Override
    @Transactional
    public void deleteRoleByIds(List<Integer> ids) {
        iRoleService.update(new UpdateWrapper<Role>().set("deleted", 1).in("id", ids));
        iUserRoleService.update(new UpdateWrapper<UserRole>().set("deleted", 1).in("role_id", ids));
        // 移除角色下所配置的菜单
        iRoleMenuService.update(new UpdateWrapper<RoleMenu>().set("deleted", 1).in("role_id", ids));
        // 移除角色下所配置的权限
        iRolePermService.update(new UpdateWrapper<RolePerm>().set("deleted", 1).in("role_id", ids));
        iRoleOrgService.update(new UpdateWrapper<RoleOrg>().set("deleted", 1).in("role_id", ids));
    }

    @Override
    @Transactional
    public void saveRoleSettings(Role role) {
        List<Integer> menuIds = role.getMenuIds();
        List<Integer> permIds = role.getPermIds();
        List<Integer> orgIds = role.getOrgIds();
        Integer roleId = role.getId();
        iRoleMenuService.update(new UpdateWrapper<RoleMenu>().set("deleted", 1).in("role_id", roleId));
        iRolePermService.update(new UpdateWrapper<RolePerm>().set("deleted", 1).in("role_id", roleId));
        iRoleOrgService.update(new UpdateWrapper<RoleOrg>().set("deleted", 1).in("role_id", roleId));

        List<RoleMenu> roleMenus = new ArrayList<>();
        menuIds.forEach(menuId -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);
            roleMenus.add(roleMenu);
        });
        iRoleMenuService.saveBatch(roleMenus);

        List<RolePerm> rolePerms = new ArrayList<>();
        permIds.forEach(permId -> {
            RolePerm rolePerm = new RolePerm();
            rolePerm.setPermId(permId);
            rolePerm.setRoleId(roleId);
            rolePerms.add(rolePerm);
        });
        iRolePermService.saveBatch(rolePerms);

        List<RoleOrg> roleOrgs = new ArrayList<>();
        orgIds.forEach(orgId -> {
            RoleOrg roleOrg = new RoleOrg();
            roleOrg.setOrgId(orgId);
            roleOrg.setRoleId(roleId);
            roleOrgs.add(roleOrg);
        });
        iRoleOrgService.saveBatch(roleOrgs);
    }
}
